<script setup>
import { ref, onMounted, reactive, defineEmits, computed, watch, onUnmounted } from 'vue';
import axios from 'axios';

// 定义事件
const emit = defineEmits(['close']);

// 座位相关常量
const GRID_WIDTH = 100;
const GRID_HEIGHT = 60;
const SCALE_FACTOR = 0.6; // 缩放比例

// 用户数据 - 从主界面获取
const userData = ref(null);
// 座位数据
const seats = ref([]);
// 加载状态
const loading = ref(false);
// 选中的座位
const selectedSeat = ref(null);
// 当前楼层
const currentFloor = ref('floor1'); // 默认为一楼
// 订单数据
const orderForm = reactive({
  user_id: '',
  equipment_id: '',
  time_length: 1, // 默认上机时长为1小时
  equipment_type: 0, // 默认设备类型
  region_id: '', // 区域ID
});
// 上机成功消息
const successMessage = ref('');
// 错误消息
const errorMessage = ref('');
// 时间计算相关状态
const timeCalculation = reactive({
  estimatedTime: 0, // 预计可用时间（小时）
  remainingBalance: 0, // 剩余余额
  calculating: false, // 是否在计算中
  timer: null, // 计时器
  showLowBalanceWarning: false // 余额不足警告
});

// 添加新的状态变量
const onlineStatus = ref(false); // 是否处于上机状态
const currentOrderId = ref(''); // 当前订单编号
const startTime = ref(null); // 上机开始时间
const usedTime = ref(0); // 已使用时间（分钟）
const usedFee = ref(0); // 已产生费用
const usageTimer = ref(null); // 计时器

// 组件变量定义部分，添加 refreshTimer
const refreshTimer = ref(null);

// 添加刷新状态变量
const isRefreshing = ref(false);
const lastRefreshTime = ref(new Date());

// 添加刷新进度状态
const refreshProgress = ref(0);
const refreshCountdown = ref(10);
const refreshCountdownTimer = ref(null);

// 添加本地存储键名常量
const ONLINE_STATUS_KEY = 'embarkation_online_status';

// 计算属性：当前可用时间（小时）
const maxTimeHours = computed(() => {
  if (!selectedSeat.value || !userData.value || !userData.value.balance) return 0;
  
  // 计算用户余额可以使用的最大小时数
  const balance = parseFloat(userData.value.balance);
  const hourlyRate = selectedSeat.value.region_price || 0;
  
  if (hourlyRate <= 0) return 0;
  
  return Math.floor(balance / hourlyRate);
});

// 获取用户信息
function getUserInfo() {
  try {
    const userInfoStr = localStorage.getItem('userInfo');
    if (userInfoStr) {
      const parsedUserInfo = JSON.parse(userInfoStr);
      console.log('解析到的用户信息:', parsedUserInfo);
      
      // 确保用户信息包含必要字段
      userData.value = {
        ...parsedUserInfo,
        // 确保number字段存在，用于下订单
        number: parsedUserInfo.number || parsedUserInfo.id,
        // 确保id字段存在，用于显示
        id: parsedUserInfo.id || parsedUserInfo.number,
        // 确保realname或username字段存在，用于显示
        realname: parsedUserInfo.realname || parsedUserInfo.name || parsedUserInfo.username || '未知用户'
      };
      
      console.log('设置后的用户数据:', userData.value);
      
      // 设置订单表单的用户ID
      orderForm.user_id = userData.value.number;
      console.log('设置订单表单用户ID:', orderForm.user_id);
      
      // 检查用户余额是否存在
      if (!userData.value.balance) {
        console.warn('用户余额不存在，设置为默认值0');
        userData.value.balance = 0;
      }
    } else {
      errorMessage.value = '请先登录后再使用上机功能';
      console.warn('localStorage中没有找到userInfo');
    }
  } catch (error) {
    console.error('解析用户信息时出错:', error);
    errorMessage.value = '读取用户信息失败';
  }
}

// 获取所有座位
async function getAllSeats(silent = false) {
  // 设置刷新状态
  isRefreshing.value = true;

  // 只有在非静默模式下才显示加载状态
  if (!silent) {
    loading.value = true;
  }
  
  try {
    console.log('开始获取座位数据...');
    const response = await axios.post('http://localhost:9001/internet/getAllSeats');
    
    if (silent) {
      console.log('静默刷新座位数据，收到响应');
    } else {
      console.log('座位数据响应:', response.data);
    }
    
    // 更新最后刷新时间
    lastRefreshTime.value = new Date();
    
    // 重置刷新倒计时
    refreshCountdown.value = 10;
    refreshProgress.value = 0;
    
    if (response.data && Array.isArray(response.data)) {
      // 获取所有座位数据
      const allSeats = response.data;
      console.log('获取座位数据成功，总数:', allSeats.length);
      
      // 保存当前选中座位的ID以便刷新后恢复选择
      const selectedSeatId = selectedSeat.value ? selectedSeat.value.id : null;
      
      // 处理座位数据，添加必要的属性
      seats.value = allSeats.map(seat => {
        return {
          ...seat,
          // 确保每个座位有所需的属性
          row_position: seat.row_position || 0,
          col_position: seat.col_position || 0,
          floor: seat.floor || 1,
          module_type: seat.module_type !== undefined ? seat.module_type : (seat.seat_id === 0 ? 0 : 1)
        };
      });
      
      // 获取所有区域信息以补充座位显示信息
      try {
        if (!silent) {
          console.log('开始获取区域数据...');
        }
        const regionResponse = await axios.post('http://localhost:9001/internet/findRegion');
        
        if (!silent) {
          console.log('区域数据响应:', regionResponse.data);
        }
        
        if (regionResponse.data && Array.isArray(regionResponse.data)) {
          const regions = regionResponse.data;
          
          if (!silent) {
            console.log('获取区域数据成功，总数:', regions.length);
          }
          
          // 为每个座位添加区域信息
          seats.value = seats.value.map(seat => {
            if (seat.region_id) {
              const region = regions.find(r => r.region_id === seat.region_id);
              if (region) {
                return {
                  ...seat,
                  region_lv: region.region_lv || seat.region_lv,
                  region_price: region.region_price || seat.region_price
                };
              }
            }
            return seat;
          });
        }
      } catch (regionError) {
        console.error('获取区域数据失败:', regionError);
        if (!silent) {
          console.error('错误详情:', regionError.response?.data);
          console.warn('使用座位自带区域信息');
        }
      }
      
      // 渲染座位布局
      setTimeout(() => {
        createGrid();
        addSeatsToLayout();
        
        // 如果有选中的座位，恢复选择
        if (selectedSeatId) {
          const updatedSeat = seats.value.find(s => s.id === selectedSeatId);
          if (updatedSeat) {
            // 延迟一点再选中，确保DOM已经更新
            setTimeout(() => {
              selectSeat(updatedSeat);
              // 高亮显示选中的座位
              const seatElement = document.querySelector(`.seat-item[data-id="${selectedSeatId}"]`);
              if (seatElement) {
                seatElement.classList.add('selected');
              }
            }, 50);
          }
        }
      }, 100);
    } else {
      if (!silent) {
        console.warn('获取座位数据格式不正确:', response.data);
        errorMessage.value = '获取座位数据格式不正确';
      }
    }
  } catch (error) {
    if (!silent) {
      console.error('获取座位数据失败:', error);
      console.error('错误详情:', error.response?.data);
      errorMessage.value = `获取座位数据失败: ${error.message}`;
    } else {
      console.error('静默刷新座位数据失败:', error.message);
    }
  } finally {
    // 取消刷新状态
    isRefreshing.value = false;
    
    // 只有在非静默模式下才更新加载状态
    if (!silent) {
      loading.value = false;
    }
  }
}

// 手动刷新座位数据
function refreshSeats() {
  // 防止重复刷新
  if (isRefreshing.value) return;
  
  console.log('手动刷新座位数据...');
  getAllSeats(false); // 手动刷新不使用静默模式，显示加载状态
}

// 创建网格
function createGrid() {
  const gridContainer = document.getElementById('embarkationGridContainer');
  if (!gridContainer) {
    console.error('找不到网格容器元素');
    return;
  }

  gridContainer.innerHTML = ''; // 清空现有内容

  // 创建12x10的网格
  for (let row = 0; row < 10; row++) {
    for (let col = 0; col < 12; col++) {
      const cell = document.createElement('div');
      cell.className = 'grid-cell';
      cell.style.gridRow = row + 1;
      cell.style.gridColumn = col + 1;
      cell.style.width = `${GRID_WIDTH * SCALE_FACTOR}px`;
      cell.style.height = `${GRID_HEIGHT * SCALE_FACTOR}px`;

      // 添加坐标标签
      const label = document.createElement('div');
      label.className = 'grid-cell-label';
      label.textContent = `${row + 1},${col + 1}`;
      label.style.fontSize = '8px';
      cell.appendChild(label);

      gridContainer.appendChild(cell);
    }
  }
}

// 添加座位到布局
function addSeatsToLayout() {
  const seatMap = document.getElementById('embarkationSeatMap');
  if (!seatMap) {
    console.error('找不到座位容器元素');
    return;
  }
  
  // 获取当前显示的座位数据用于比较
  const currentSeats = {};
  document.querySelectorAll('.seat-item').forEach(seatEl => {
    const id = seatEl.dataset.id;
    if (id) {
      currentSeats[id] = {
        element: seatEl,
        status: seatEl.classList.contains('online') ? 1 : 
                seatEl.classList.contains('maintenance') ? 3 : 
                seatEl.classList.contains('available') ? 2 : 0
      };
    }
  });
  
  // 清空现有内容
  const existingSeats = seatMap.querySelectorAll('.seat-item');
  existingSeats.forEach(seat => seat.remove());
  
  // 获取当前楼层的座位
  const currentFloorSeats = seats.value.filter(seat => 
    seat.floor === (currentFloor.value === 'floor1' ? 1 : 2)
  );
  
  console.log(`添加${currentFloor.value === 'floor1' ? '一' : '二'}楼座位到布局，数量:`, currentFloorSeats.length);
  
  if (currentFloorSeats.length === 0) {
    const noSeatsMessage = document.createElement('div');
    noSeatsMessage.className = 'no-seats-message';
    noSeatsMessage.textContent = '';
    seatMap.appendChild(noSeatsMessage);
    return;
  }
  
  // 添加每个座位
  currentFloorSeats.forEach(seat => {
    // 只显示座位类型（不显示模块）
    if (seat.module_type !== 0) return;
    
    // 创建座位元素
    const seatElement = document.createElement('div');
    seatElement.className = 'seat-item';
    seatElement.dataset.id = seat.id;
    
    // 检查状态是否发生变化，添加状态变化标记
    const previousSeat = currentSeats[seat.id];
    const statusChanged = previousSeat && previousSeat.status !== seat.status;
    
    // 根据状态设置样式和点击事件
    if (seat.status === 2) { // 离线状态，可选择
      seatElement.classList.add('available');
      seatElement.addEventListener('click', () => selectSeat(seat));
    } else {
      seatElement.classList.add('unavailable');
      if (seat.status === 1) seatElement.classList.add('online');
      if (seat.status === 3) seatElement.classList.add('maintenance');
    }
    
    // 如果状态发生变化，添加突出显示效果
    if (statusChanged) {
      seatElement.classList.add('status-changed');
      // 3秒后移除高亮效果
      setTimeout(() => {
        seatElement.classList.remove('status-changed');
      }, 3000);
    }
    
    // 设置座位位置
    const left = (seat.col_position - 1) * GRID_WIDTH * SCALE_FACTOR;
    const top = (seat.row_position - 1) * GRID_HEIGHT * SCALE_FACTOR;
    seatElement.style.left = `${left}px`;
    seatElement.style.top = `${top}px`;
    seatElement.style.width = `${GRID_WIDTH * SCALE_FACTOR}px`;
    seatElement.style.height = `${GRID_HEIGHT * SCALE_FACTOR}px`;
    
    // 设置座位内容
    seatElement.innerHTML = `
      <div class="seat-content">
        <span class="seat-name">${seat.item_name || `座位${seat.id}`}</span>
        <span class="seat-status">${getStatusText(seat.status)}</span>
        <span class="seat-region">${seat.region_lv || '区域' + (seat.region_id || '?')}</span>
        <span class="seat-price">${seat.region_price ? `¥${seat.region_price}/h` : ''}</span>
      </div>
    `;
    
    // 添加到容器
    seatMap.appendChild(seatElement);
  });
}

// 获取状态文本
function getStatusText(status) {
  switch (status) {
    case 0: return '无状态';
    case 1: return '在线';
    case 2: return '离线';
    case 3: return '维修中';
    default: return '未知';
  }
}

// 选择座位
function selectSeat(seat) {
  // 清除之前选中的座位
  document.querySelectorAll('.seat-item.selected').forEach(el => {
    el.classList.remove('selected');
  });
  
  // 标记当前座位为选中
  const seatElement = document.querySelector(`.seat-item[data-id="${seat.id}"]`);
  if (seatElement) {
    seatElement.classList.add('selected');
  }
  
  selectedSeat.value = seat;
  orderForm.equipment_id = seat.id;
  orderForm.region_id = seat.region_id;
  
  console.log('选择座位:', seat);
  
  // 开始计算可用时间
  startTimeCalculation();
}

// 开始时间计算
function startTimeCalculation() {
  // 停止之前的计算
  stopTimeCalculation();
  
  // 如果没有选中座位或没有用户数据，不执行计算
  if (!selectedSeat.value || !userData.value) return;
  
  // 设置计算状态
  timeCalculation.calculating = true;
  
  // 立即执行一次计算
  calculateUsageTime();
  
  // 设置定时器，每10秒更新一次
  timeCalculation.timer = setInterval(calculateUsageTime, 10000);
}

// 停止时间计算
function stopTimeCalculation() {
  timeCalculation.calculating = false;
  if (timeCalculation.timer) {
    clearInterval(timeCalculation.timer);
    timeCalculation.timer = null;
  }
}

// 计算使用时间
function calculateUsageTime() {
  if (!selectedSeat.value || !userData.value) return;
  
  const balance = parseFloat(userData.value.balance || 0);
  const hourlyRate = parseFloat(selectedSeat.value.region_price || 0);
  
  if (hourlyRate <= 0) {
    timeCalculation.estimatedTime = 0;
    timeCalculation.remainingBalance = balance;
    return;
  }
  
  // 计算可使用的小时数
  const maxHours = Math.floor(balance / hourlyRate);
  timeCalculation.estimatedTime = maxHours;
  
  // 计算剩余余额
  const remainingBalance = balance - (orderForm.time_length * hourlyRate);
  timeCalculation.remainingBalance = remainingBalance > 0 ? remainingBalance : 0;
  
  // 检查余额是否不足
  timeCalculation.showLowBalanceWarning = balance <= 5;
  
  console.log('时间计算结果:', {
    balance,
    hourlyRate,
    maxHours,
    remainingBalance,
    showWarning: timeCalculation.showLowBalanceWarning
  });
}

// 刷新用户余额信息
async function refreshUserBalance() {
  try {
    // 从localStorage获取用户信息
    const userInfoStr = localStorage.getItem('userInfo');
    if (!userInfoStr) {
      console.warn('无法刷新余额: 未找到用户信息');
      return;
    }
    
    const userInfo = JSON.parse(userInfoStr);
    // 使用phone和cipher字段重新登录以获取最新用户信息
    const phone = userInfo.phone;
    const cipher = userInfo.cipher;
    
    if (!phone || !cipher) {
      console.warn('无法刷新余额: 缺少登录信息');
      return;
    }
    
    console.log('正在刷新用户余额...');
    
    // 创建表单数据
    const formData = new FormData();
    formData.append('phone', phone);
    formData.append('cipher', cipher);
    
    // 使用登录接口重新获取用户信息
    const response = await axios.post('http://localhost:9001/user/login', formData);
    
    if (response.data && response.data.number) {
      console.log('获取最新用户信息成功:', response.data);
      
      // 更新本地存储的用户信息
      localStorage.setItem('userInfo', JSON.stringify(response.data));
      
      // 更新当前组件中的用户数据
      userData.value = {
        ...response.data,
        // 确保显示字段存在
        realname: response.data.realname || response.data.name || response.data.username || '未知用户'
      };
      
      console.log('用户余额已更新为:', userData.value.balance);
    } else {
      console.warn('刷新用户余额失败: 未获取到数据');
    }
  } catch (error) {
    console.error('刷新用户余额时出错:', error);
    // 不显示错误消息，因为这是背景操作
  }
}

// 创建上机订单
async function createOrder() {
  if (!userData.value) {
    errorMessage.value = '请先登录再使用上机功能';
    return;
  }
  
  // 从localStorage重新获取最新的用户信息，确保数据是最新的
  try {
    const userInfoStr = localStorage.getItem('userInfo');
    if (userInfoStr) {
      userData.value = JSON.parse(userInfoStr);
    }
  } catch (error) {
    console.error('解析用户信息时出错:', error);
  }
  
  // 检查用户账号 - 确保使用number字段
  const userNumber = userData.value.number;
  
  if (!userNumber) {
    errorMessage.value = '无法获取用户账号，请重新登录';
    return;
  }
  
  if (!selectedSeat.value || !orderForm.equipment_id) {
    errorMessage.value = '请先选择座位';
    return;
  }
  
  // 检查用户余额是否足够
  const balance = parseFloat(userData.value.balance || 0);
  const hourlyRate = parseFloat(selectedSeat.value.region_price || 0);
  
  if (balance < hourlyRate) {
    errorMessage.value = '余额不足，请先充值';
    return;
  }
  
  loading.value = true;
  errorMessage.value = '';
  successMessage.value = '';
  
  try {
    // 使用当前时间作为开始时间
    const now = new Date();
    
    // 格式化时间为正确的LocalDateTime格式 YYYY-MM-DDThh:mm:ss
    const formattedDateTime = now.toISOString().slice(0, 19);
    
    // 构建请求表单数据 - 与测试成功的数据格式保持一致
    const formData = new FormData();
    formData.append('number', userNumber); // 用户账号
    formData.append('eq_id', selectedSeat.value.id); // 座位编号
    formData.append('start_time', formattedDateTime); // 开始时间，格式为: YYYY-MM-DDThh:mm:ss
    formData.append('state', 0); // 上机状态
    formData.append('favorable_id', 4011); // 优惠编号
    
    console.log('上机请求数据:', {
      number: userNumber,
      eq_id: selectedSeat.value.id,
      start_time: formattedDateTime,
      state: 0,
      favorable_id: 4011
    });
    
    // 发送请求
    const response = await axios.post('http://localhost:9001/order/createInternetOrder', formData);
    
    console.log('上机响应:', response.data);
    
    // 检查响应内容是否包含'失败'或者'已经上过机'
    if (response.data && typeof response.data === 'string' && (response.data.includes('失败') || response.data.includes('已经上过机'))) {
      // 服务器返回了失败消息
      errorMessage.value = response.data;
      console.error('上机失败:', response.data);
    } else if (response.data) {
      // 从响应中获取订单编号
      const orderNumber = typeof response.data === 'string' 
        ? response.data
        : response.data.orderId || '订单已创建';
      
      // 保存订单ID和开始时间
      currentOrderId.value = orderNumber;
      startTime.value = now;
      
      // 更新上机状态
      onlineStatus.value = true;
      
      // 【新增】保存上机状态到本地存储
      saveOnlineStatusToLocalStorage({
        orderId: orderNumber,
        startTime: now.toISOString(),
        equipmentId: selectedSeat.value.id,
        regionId: selectedSeat.value.region_id,
        seatName: selectedSeat.value.item_name,
        hourlyRate: selectedSeat.value.region_price
      });
      
      // 开始计时
      startUsageTimer();
        
      successMessage.value = `上机成功！订单号: ${orderNumber}`;
      console.log('上机成功:', orderNumber);
      
      // 刷新座位数据
      await getAllSeats();
      
      // 刷新用户余额（在后台进行，不影响UI流程）
      refreshUserBalance();
    } else {
      errorMessage.value = '上机失败，未收到预期的响应';
    }
  } catch (error) {
    console.error('上机请求失败:', error);
    console.error('错误详情:', error.response?.data);
    console.error('请求配置:', error.config);
    
    // 提供更友好的错误信息
    if (error.response) {
      // 服务器返回了错误状态码
      if (error.response.status === 404) {
        errorMessage.value = '上机失败: 上机接口不存在，请联系管理员';
      } else if (error.response.status === 500) {
        const errorDetail = error.response.data?.message || error.response.data?.error || '服务器内部错误';
        errorMessage.value = `上机失败: ${errorDetail}`;
      } else if (error.response.status === 400) {
        const errorDetail = error.response.data?.message || error.response.data?.error || '请求参数错误';
        errorMessage.value = `上机失败: ${errorDetail}`;
      } else if (error.response.data && typeof error.response.data === 'string') {
        errorMessage.value = `上机失败: ${error.response.data}`;
      } else {
        errorMessage.value = `上机失败: 服务器错误 (${error.response.status})`;
      }
    } else if (error.code === 'ECONNABORTED') {
      errorMessage.value = '上机失败: 请求超时，请检查网络';
    } else if (!navigator.onLine) {
      errorMessage.value = '上机失败: 网络连接已断开';
    } else {
      errorMessage.value = `上机失败: ${error.message || '未知错误'}`;
    }
  } finally {
    loading.value = false;
  }
}

// 增强 handleDeplane 函数的下机处理逻辑
async function handleDeplane() {
  if (!onlineStatus.value || !currentOrderId.value) {
    errorMessage.value = '当前不在上机状态，无法下机';
    return;
  }
  
  loading.value = true;
  errorMessage.value = '';
  successMessage.value = '';
  
  try {
    // 确保数据格式正确
    const orderId = currentOrderId.value.trim();
    
    // 使用当前时间作为结束时间
    const now = new Date();
    // 格式化时间为正确的LocalDateTime格式 YYYY-MM-DDThh:mm:ss
    const formattedDateTime = now.toISOString().slice(0, 19);
    
    // 构建表单数据
    const formData = new FormData();
    formData.append('order_id', orderId); // 订单编号
    formData.append('end_time', formattedDateTime); // 当前时间作为结束时间，使用正确格式
    formData.append('text', '网费'); // 说明，固定为网费
    formData.append('favorable_id', 4011); // 优惠编号为4011
    
    console.log('下机请求数据:', {
      order_id: orderId,
      end_time: formattedDateTime,
      text: '网费',
      favorable_id: 4011
    });
    
    // 发送请求
    const response = await axios.post('http://localhost:9001/order/deplane', formData);
    
    console.log('下机响应:', response.data);
    
    // 立即清除本地存储状态，不等待响应处理
    // 无论响应如何，都先清除本地状态
    clearOnlineStatusFromLocalStorage();
    
    // 根据响应内容更新UI
    if (response.data && typeof response.data === 'string') {
      // 检查是否存在"失败"字样
      if (response.data.includes('失败')) {
        successMessage.value = `下机失败: ${response.data}`;
        // 下机失败，但由于我们已经清除了本地存储，现在需要恢复它
        saveOnlineStatusToLocalStorage({
          orderId: currentOrderId.value,
          startTime: startTime.value.toISOString(),
          equipmentId: selectedSeat.value?.id,
          regionId: selectedSeat.value?.region_id,
          seatName: selectedSeat.value?.item_name,
          hourlyRate: selectedSeat.value?.region_price
        });
      } else {
        successMessage.value = `下机成功: ${response.data}`;
        // 重置上机状态
        resetOnlineStatus();
        
        // 刷新座位数据
        await getAllSeats();
        
        // 刷新用户余额
        await refreshUserBalance();
      }
    } else {
      // 如果没有得到预期响应，但已发送请求，则认为下机成功
      successMessage.value = '下机操作已完成，但未获取到详细信息';
      resetOnlineStatus();
    }
  } catch (error) {
    console.error('下机请求失败:', error);
    
    // 尽管请求失败，我们也尝试清除本地状态
    // 因为用户明确要求下机，我们应尊重这个意图
    clearOnlineStatusFromLocalStorage();
    resetOnlineStatus();
    
    // 显示用户友好的错误信息
    errorMessage.value = `下机请求失败，但已重置本地状态: ${error.message || '未知错误'}`;
    
    // ... 其余错误处理代码 ...
  } finally {
    loading.value = false;
  }
}

// 重置上机状态
function resetOnlineStatus() {
  onlineStatus.value = false;
  currentOrderId.value = '';
  startTime.value = null;
  usedTime.value = 0;
  usedFee.value = 0;
  
  // 停止计时器
  stopUsageTimer();
  
  // 重置选择的座位
  resetSelection();
}

// 开始使用时间计时器
function startUsageTimer() {
  // 确保先停止之前的计时器
  stopUsageTimer();
  
  // 如果没有开始时间，则不启动计时器
  if (!startTime.value) return;
  
  // 立即执行一次计算
  calculateUsedTime();
  
  // 设置计时器，每10秒更新一次
  usageTimer.value = setInterval(calculateUsedTime, 10000);
}

// 停止使用时间计时器
function stopUsageTimer() {
  if (usageTimer.value) {
    clearInterval(usageTimer.value);
    usageTimer.value = null;
  }
}

// 计算已使用时间和费用
function calculateUsedTime() {
  if (!startTime.value || !selectedSeat.value) return;
  
  const now = new Date();
  const start = new Date(startTime.value);
  
  // 计算已使用分钟数
  const diffMs = now - start;
  const diffMinutes = Math.floor(diffMs / 60000); // 毫秒转分钟
  usedTime.value = diffMinutes;
  
  // 计算已产生费用 - 改进计算精度
  const hourlyRate = parseFloat(selectedSeat.value.region_price || 0);
  // 更精确的费用计算，考虑分钟数的精确转换
  usedFee.value = parseFloat(((hourlyRate / 60) * diffMinutes).toFixed(2));
  
  // 计算剩余余额 - 添加安全检查
  const balance = parseFloat(userData.value?.balance || 0);
  const newRemainingBalance = Math.max(0, parseFloat((balance - usedFee.value).toFixed(2)));
  timeCalculation.remainingBalance = newRemainingBalance;
  
  // 添加低余额预警逻辑
  const warningThreshold = hourlyRate * 0.5; // 半小时的费用作为警告阈值
  timeCalculation.showLowBalanceWarning = newRemainingBalance <= warningThreshold;
  
  console.log('计时更新:', {
    usedMinutes: diffMinutes,
    usedFee: usedFee.value,
    remainingBalance: timeCalculation.remainingBalance,
    warningThreshold
  });
}

// 格式化时间为"几分钟前"
function formatTimeAgo(date) {
  const now = new Date();
  const diffSeconds = Math.floor((now - date) / 1000);
  
  if (diffSeconds < 10) return '刚刚';
  if (diffSeconds < 60) return `${diffSeconds}秒前`;
  
  const diffMinutes = Math.floor(diffSeconds / 60);
  if (diffMinutes < 60) return `${diffMinutes}分钟前`;
  
  const diffHours = Math.floor(diffMinutes / 60);
  return `${diffHours}小时前`;
}

// 格式化时间显示（分钟转为小时和分钟）
function formatTime(minutes) {
  const hours = Math.floor(minutes / 60);
  const mins = minutes % 60;
  return `${hours > 0 ? hours + '小时' : ''}${mins}分钟`;
}

// 重置选择
function resetSelection() {
  selectedSeat.value = null;
  orderForm.equipment_id = '';
  orderForm.region_id = '';
  
  // 清除选中样式
  document.querySelectorAll('.seat-item.selected').forEach(el => {
    el.classList.remove('selected');
  });
  
  // 停止时间计算
  stopTimeCalculation();
}

// 切换楼层
function switchFloor(floor) {
  if (currentFloor.value === floor) return;
  
  currentFloor.value = floor;
  console.log(`切换到${floor === 'floor1' ? '一' : '二'}楼`);
  
  // 重置选择
  resetSelection();
  
  // 重新渲染座位
  addSeatsToLayout();
}

// 关闭弹窗
function closeModal() {
  if (onlineStatus.value) {
    if (confirm('您当前正在上机中，确定要关闭窗口吗？(不会影响您的上机状态)')) {
      // 停止时间计算
      stopTimeCalculation();
      
      // 触发关闭事件
      emit('close');
    }
  } else {
    // 停止时间计算
    stopTimeCalculation();
    
    // 触发关闭事件
    emit('close');
  }
}

// 监听选中座位变化
watch(selectedSeat, (newSeat) => {
  if (newSeat) {
    // 根据座位区域价格和用户余额计算最大可用时间
    calculateUsageTime();
  } else {
    stopTimeCalculation();
  }
});

// 启动刷新倒计时
function startRefreshCountdown() {
  // 清除可能存在的旧计时器
  if (refreshCountdownTimer.value) {
    clearInterval(refreshCountdownTimer.value);
  }
  
  // 设置刷新倒计时和进度条更新
  refreshCountdownTimer.value = setInterval(() => {
    refreshCountdown.value -= 0.1;
    refreshCountdown.value = parseFloat(refreshCountdown.value.toFixed(1));
    refreshProgress.value = (10 - refreshCountdown.value) / 10 * 100;
    
    if (refreshCountdown.value <= 0) {
      clearInterval(refreshCountdownTimer.value);
      // 自动刷新将通过组件挂载时设置的refreshTimer触发
    }
  }, 100);
}

// 组件挂载时获取数据
onMounted(async () => {
  try {
    console.log('上机组件挂载中...');
    
    // 获取用户信息
    getUserInfo();
    
    // 获取座位数据
    await getAllSeats(false); // 首次加载不静默
    
    // 检查当前上机状态
    await checkCurrentOnlineStatus();
    
    // 设置初始楼层
    currentFloor.value = 'floor1';
    
    // 启动刷新倒计时
    startRefreshCountdown();
    
    // 设置定时刷新座位数据
    refreshTimer.value = setInterval(async () => {
      console.log('定时刷新座位数据...');
      await getAllSeats(true); // 定时刷新使用静默模式
      // 刷新完成后重新启动倒计时
      startRefreshCountdown();
    }, 10000); // 每10秒刷新一次
    
    console.log('上机组件挂载完成，已设置座位自动刷新');
  } catch (error) {
    console.error('上机组件挂载失败:', error);
    errorMessage.value = '初始化上机界面失败，请刷新页面重试';
  }
});

// 添加新函数检查当前上机状态
async function checkCurrentOnlineStatus() {
  if (!userData.value || !userData.value.number) {
    console.log('无法检查上机状态: 用户未登录');
    return;
  }
  
  // 【新增】先从本地存储恢复状态
  const localStatusRestored = restoreOnlineStatusFromLocalStorage();
  
  // 如果本地没有状态或恢复失败，从服务器检查
  if (!localStatusRestored) {
    try {
      console.log('从服务器检查用户当前上机状态...');
      const userNumber = userData.value.number;
      
      // 构建请求参数
      const formData = new FormData();
      formData.append('number', userNumber);
      
      // 请求当前用户的上机状态
      const response = await axios.post('http://localhost:9001/order/getCurrentOrder', formData);
      
      if (response.data && response.data.order_id) {
        console.log('检测到用户有进行中的上机记录:', response.data);
        
        // 恢复上机状态
        restoreOnlineStatus(response.data);
        
        // 保存到本地存储以便未来恢复
        saveOnlineStatusToLocalStorage({
          orderId: response.data.order_id,
          startTime: response.data.start_time || (response.data.create_time || new Date().toISOString()),
          equipmentId: response.data.equipment_id,
          regionId: response.data.region_id,
          hourlyRate: response.data.region_price || selectedSeat.value?.region_price
        });
      } else {
        console.log('用户当前没有进行中的上机记录');
        // 确保状态为未上机
        onlineStatus.value = false;
        // 清除可能存在的过期本地存储
        clearOnlineStatusFromLocalStorage();
      }
    } catch (error) {
      console.error('从服务器检查上机状态失败:', error);
      // 注意：如果服务器检查失败但本地有状态，我们保留本地状态
    }
  } else {
    // 如果已从本地恢复，尝试静默验证服务器状态（不影响UI）
    validateOnlineStatusWithServer().catch(error => {
      console.warn('静默验证上机状态失败:', error);
    });
  }
}

// 监听订单表单的时长变化
watch(() => orderForm.time_length, (newValue) => {
  // 确保值为有效数字
  if (isNaN(newValue) || newValue < 1) {
    orderForm.time_length = 1;
  } else if (newValue > maxTimeHours.value) {
    // 限制最大时长为可用时间
    orderForm.time_length = maxTimeHours.value;
  }
  
  // 重新计算使用时间
  calculateUsageTime();
});

// 组件卸载时清理计时器
onUnmounted(() => {
  stopTimeCalculation();
  stopUsageTimer();
  
  // 清除座位刷新定时器
  if (refreshTimer.value) {
    clearInterval(refreshTimer.value);
    refreshTimer.value = null;
    console.log('已清除座位刷新定时器');
  }
  
  // 清除刷新倒计时定时器
  if (refreshCountdownTimer.value) {
    clearInterval(refreshCountdownTimer.value);
    refreshCountdownTimer.value = null;
  }
});

// 【新增】保存上机状态到本地存储的函数
function saveOnlineStatusToLocalStorage(statusData) {
  try {
    localStorage.setItem(ONLINE_STATUS_KEY, JSON.stringify({
      ...statusData,
      userId: userData.value?.number, // 保存用户ID，确保只恢复正确用户的状态
      timestamp: new Date().getTime() // 保存时间戳用于验证数据有效性
    }));
    console.log('上机状态已保存到本地存储');
  } catch (error) {
    console.error('保存上机状态到本地存储失败:', error);
  }
}

// 【新增】从本地存储清除上机状态的函数
function clearOnlineStatusFromLocalStorage() {
  try {
    localStorage.removeItem(ONLINE_STATUS_KEY);
    console.log('上机状态已从本地存储中清除');
  } catch (error) {
    console.error('清除本地存储中的上机状态失败:', error);
  }
}

// 【新增】从本地存储恢复上机状态
function restoreOnlineStatusFromLocalStorage() {
  try {
    const storedStatusJSON = localStorage.getItem(ONLINE_STATUS_KEY);
    if (!storedStatusJSON) {
      console.log('本地存储中没有上机状态');
      return false;
    }
    
    const storedStatus = JSON.parse(storedStatusJSON);
    
    // 验证数据有效性
    if (!storedStatus || !storedStatus.orderId || !storedStatus.userId) {
      console.warn('本地存储中的上机状态数据不完整');
      clearOnlineStatusFromLocalStorage();
      return false;
    }
    
    // 验证是否是当前用户的数据
    if (storedStatus.userId !== userData.value.number) {
      console.log('本地存储的上机状态属于其他用户');
      return false;
    }
    
    // 检查数据是否过期（例如，超过24小时）
    const maxAgeMs = 24 * 60 * 60 * 1000; // 24小时
    if (storedStatus.timestamp && (new Date().getTime() - storedStatus.timestamp > maxAgeMs)) {
      console.warn('本地存储的上机状态已过期');
      clearOnlineStatusFromLocalStorage();
      return false;
    }
    
    // 添加额外验证: 检查时间是否过长
    // 如果上机时间超过24小时，视为异常状态，清除本地存储
    const maxSessionLengthMs = 24 * 60 * 60 * 1000; // 24小时
    const startTimeDate = new Date(storedStatus.startTime);
    if (new Date().getTime() - startTimeDate.getTime() > maxSessionLengthMs) {
      console.warn('检测到异常长时间上机状态，自动重置');
      clearOnlineStatusFromLocalStorage();
      return false;
    }
    
    console.log('从本地存储恢复上机状态:', storedStatus);
    
    // 恢复状态
    onlineStatus.value = true;
    currentOrderId.value = storedStatus.orderId;
    startTime.value = new Date(storedStatus.startTime);
    
    // 尝试找到对应的座位
    if (storedStatus.equipmentId) {
      const activeSeat = seats.value.find(seat => seat.id === storedStatus.equipmentId);
      if (activeSeat) {
        selectedSeat.value = activeSeat;
        orderForm.equipment_id = activeSeat.id;
        orderForm.region_id = activeSeat.region_id || storedStatus.regionId;
        
        // 突出显示选中的座位
        setTimeout(() => {
          const seatElement = document.querySelector(`.seat-item[data-id="${activeSeat.id}"]`);
          if (seatElement) {
            seatElement.classList.add('selected');
          }
        }, 100);
      } else {
        console.warn('未能找到保存的座位:', storedStatus.equipmentId);
        // 创建一个临时座位对象以保持计时功能
        selectedSeat.value = {
          id: storedStatus.equipmentId,
          item_name: storedStatus.seatName || `座位${storedStatus.equipmentId}`,
          region_price: storedStatus.hourlyRate || 0,
          region_id: storedStatus.regionId
        };
      }
    }
    
    // 启动计时器
    startUsageTimer();
    
    console.log('成功从本地存储恢复上机状态');
    return true;
  } catch (error) {
    console.error('从本地存储恢复上机状态失败:', error);
    return false;
  }
}

// 【新增】与服务器验证上机状态（静默操作）
async function validateOnlineStatusWithServer() {
  if (!userData.value || !userData.value.number || !currentOrderId.value) {
    return;
  }
  
  const userNumber = userData.value.number;
  const formData = new FormData();
  formData.append('number', userNumber);
  
  // 请求当前用户的上机状态
  const response = await axios.post('http://localhost:9001/order/getCurrentOrder', formData);
  
  // 如果服务器返回没有上机记录，但本地有记录，则清除本地记录
  if (!response.data || !response.data.order_id) {
    console.warn('服务器未返回上机记录但本地有记录，可能已在其他设备下机');
    onlineStatus.value = false;
    clearOnlineStatusFromLocalStorage();
    
    // 显示提示消息
    errorMessage.value = '您的上机状态已在其他设备上结束，本地状态已重置';
    
    // 停止计时器
    stopUsageTimer();
  }
  // 如果服务器有记录且与本地不同，更新本地记录
  else if (response.data.order_id !== currentOrderId.value) {
    console.log('服务器上机记录与本地不符，更新本地状态');
    restoreOnlineStatus(response.data);
  }
}

// 【新增】根据数据恢复上机状态的通用函数
function restoreOnlineStatus(data) {
  // 恢复上机状态
  onlineStatus.value = true;
  currentOrderId.value = data.order_id;
  
  // 设置开始时间
  if (data.start_time) {
    startTime.value = new Date(data.start_time);
  } else {
    // 如果没有开始时间，使用服务器返回的订单创建时间或当前时间减去已用时间
    startTime.value = data.create_time 
      ? new Date(data.create_time) 
      : new Date(new Date().getTime() - (data.used_minutes || 0) * 60000);
  }
  
  // 找到并选中对应的座位
  if (data.equipment_id) {
    const activeSeat = seats.value.find(seat => seat.id === data.equipment_id);
    if (activeSeat) {
      selectedSeat.value = activeSeat;
      orderForm.equipment_id = activeSeat.id;
      orderForm.region_id = activeSeat.region_id;
      
      // 突出显示选中的座位
      setTimeout(() => {
        const seatElement = document.querySelector(`.seat-item[data-id="${activeSeat.id}"]`);
        if (seatElement) {
          seatElement.classList.add('selected');
        }
      }, 100);
    }
  }
  
  // 启动计时器
  startUsageTimer();
}
</script>

<template>
  <div class="modal-backdrop" @click.self="closeModal">
    <div class="embarkation-modal">
      <div class="modal-header">
        <h2 class="modal-title">网吧上机系统</h2>
        <button class="close-btn" @click="closeModal">&times;</button>
      </div>
      
      <div class="modal-body">
        <!-- 加载状态 -->
        <div v-if="loading" class="loading-overlay">
          <div class="spinner-border text-primary" role="status">
            <span class="visually-hidden">Loading...</span>
          </div>
        </div>
        
        <!-- 消息提示 -->
        <div v-if="successMessage" class="alert alert-success mt-3">
          {{ successMessage }}
        </div>
        <div v-if="errorMessage" class="alert alert-danger mt-3">
          {{ errorMessage }}
        </div>
        
        <!-- 用户信息 -->
        <div v-if="userData" class="user-info-card mb-3">
          <div class="card card-rounded">
            <div class="card-body">
              <div class="d-flex align-items-center">
                <div class="user-avatar">
                  <i class="mdi mdi-account-circle"></i>
                </div>
                <div class="user-details">
                  <h4 class="mb-1">{{ userData.realname || userData.username || '未知用户' }}</h4>
                  <div class="user-stats">
                    <span class="user-balance">余额: <strong>¥{{ userData.balance || '0.00' }}</strong></span>
                    <span class="user-id">ID: {{ userData.id || '未知' }}</span>
                    <span v-if="onlineStatus" class="user-status online">
                      <i class="mdi mdi-clock-outline"></i> 上机中
                    </span>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
        
        <!-- 上机状态面板 -->
        <div v-if="onlineStatus" class="online-status-panel mb-3">
          <div class="card border-success">
            <div class="card-header bg-success text-white d-flex justify-content-between align-items-center">
              <div>
                <i class="mdi mdi-desktop-classic"></i> 上机状态信息
              </div>
              <button class="btn btn-sm btn-light" @click="handleDeplane">
                <i class="mdi mdi-logout"></i> 下机
              </button>
            </div>
            <div class="card-body">
              <div class="row">
                <div class="col-md-6">
                  <div class="usage-info">
                    <div class="info-item">
                      <span class="info-label">订单编号:</span>
                      <span class="info-value">{{ currentOrderId }}</span>
                    </div>
                    <div class="info-item">
                      <span class="info-label">已使用时间:</span>
                      <span class="info-value">{{ formatTime(usedTime) }}</span>
                    </div>
                    <div class="info-item">
                      <span class="info-label">座位信息:</span>
                      <span class="info-value">{{ selectedSeat?.item_name || '未知' }} ({{ selectedSeat?.region_lv || '未知区域' }})</span>
                    </div>
                  </div>
                </div>
                <div class="col-md-6">
                  <div class="usage-info">
                    <div class="info-item">
                      <span class="info-label">已产生费用:</span>
                      <span class="info-value text-danger">¥{{ usedFee.toFixed(2) }}</span>
                    </div>
                    <div class="info-item">
                      <span class="info-label">剩余余额:</span>
                      <span class="info-value" :class="{'text-danger': timeCalculation.remainingBalance < 10}">
                        ¥{{ timeCalculation.remainingBalance.toFixed(2) }}
                      </span>
                    </div>
                    <div class="info-item">
                      <span class="info-label">费率:</span>
                      <span class="info-value">¥{{ selectedSeat?.region_price || '0.00' }}/小时</span>
                    </div>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
        
        <div class="row mb-3">
          <!-- 楼层切换 -->
          <div class="col-12">
            <div class="floor-selector btn-group mb-3" role="group">
              <button 
                :class="['btn', currentFloor === 'floor1' ? 'btn-primary' : 'btn-outline-primary']"
                @click="switchFloor('floor1')"
              >
                一楼
              </button>
              <button 
                :class="['btn', currentFloor === 'floor2' ? 'btn-primary' : 'btn-outline-primary']"
                @click="switchFloor('floor2')"
              >
                二楼
              </button>
            </div>
          </div>
        </div>
        
        <!-- 座位布局 -->
        <div class="row">
          <div class="col-md-8">
            <div class="card">
              <div class="card-body">
                <div class="d-flex justify-content-between align-items-center mb-3">
                  <h5 class="card-title">座位布局</h5>
                  <div class="refresh-info d-flex align-items-center">
                    <small class="text-muted me-2">
                      <span v-if="isRefreshing"><i class="mdi mdi-refresh spinning"></i> 刷新中...</span>
                      <span v-else>{{ Math.ceil(refreshCountdown) }}秒后刷新</span>
                    </small>
                    <div class="refresh-progress me-2">
                      <div class="progress" style="height: 4px; width: 50px;">
                        <div class="progress-bar" role="progressbar" :style="{ width: refreshProgress + '%' }"></div>
                      </div>
                    </div>
                    <button 
                      class="btn btn-sm btn-outline-primary" 
                      @click="refreshSeats"
                      :disabled="isRefreshing"
                    >
                      <i class="mdi mdi-refresh"></i> 刷新
                    </button>
                  </div>
                </div>
                <p class="text-muted">点击可选择的座位（离线状态）进行上机</p>
                <div id="embarkationSeatMap" class="seat-map-container">
                  <!-- 网格容器 -->
                  <div class="grid-container" id="embarkationGridContainer"></div>
                </div>
              </div>
            </div>
          </div>
          
          <!-- 上机表单 -->
          <div class="col-md-4">
            <div class="card" v-if="!onlineStatus">
              <div class="card-header">
                <h5>上机信息</h5>
              </div>
              <div class="card-body">
                <!-- 选择的座位 -->
                <div class="mb-3">
                  <label class="form-label">座位:</label>
                  <div v-if="selectedSeat" class="selected-info p-2 border rounded">
                    {{ selectedSeat.item_name }} (区域: {{ selectedSeat.region_lv || '未知' }})
                    <div class="seat-price-info mt-1">
                      <small>价格: ¥{{ selectedSeat.region_price || '0.00' }}/小时</small>
                    </div>
                  </div>
                  <div v-else class="text-muted p-2 border rounded">请从布局图中选择一个离线状态的座位</div>
                </div>
                
                <!-- 余额警告 -->
                <div v-if="timeCalculation.showLowBalanceWarning" class="alert alert-warning">
                  <i class="mdi mdi-alert-circle"></i>
                  余额不足，请及时充值以避免下机
                </div>
                
                <!-- 显示预计时间 -->
                <div class="mb-3">
                  <label class="form-label">预计可用时间:</label>
                  <div class="time-display p-2 border rounded d-flex justify-content-between">
                    <span>{{ timeCalculation.estimatedTime || 0 }} 小时</span>
                    <small v-if="timeCalculation.calculating" class="text-muted">
                      <i class="mdi mdi-refresh-circle spinning"></i> 实时计算中
                    </small>
                  </div>
                </div>
                
                <!-- 上机按钮 -->
                <div class="d-grid gap-2 mt-4">
                  <button 
                    class="btn btn-primary" 
                    @click="createOrder"
                    :disabled="loading || !selectedSeat || maxTimeHours <= 0"
                  >
                    <i class="mdi mdi-desktop-mac-dashboard"></i> 
                    确认上机
                  </button>
                </div>
              </div>
            </div>
            
            <!-- 下机按钮区域 (仅在上机状态显示) -->
            <div class="card" v-if="onlineStatus">
              <div class="card-header">
                <h5>操作</h5>
              </div>
              <div class="card-body">
                <div class="d-grid gap-2">
                  <button 
                    class="btn btn-danger" 
                    @click="handleDeplane"
                    :disabled="loading"
                  >
                    <i class="mdi mdi-logout"></i> 
                    下机
                  </button>
                  <p class="mt-2 text-muted">
                    <small>
                      <i class="mdi mdi-information-outline"></i>
                      下机后将计算网费并扣除相应金额
                    </small>
                  </p>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<style scoped>
.modal-backdrop {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, 0.5);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 2000;
}

.embarkation-modal {
  width: 90%;
  max-width: 1200px;
  max-height: 90vh;
  overflow-y: auto;
  background-color: white;
  border-radius: 8px;
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
  position: relative;
}

.modal-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 20px;
  border-bottom: 1px solid #e9ecef;
  background-color: #4B49AC;
  color: white;
  border-top-left-radius: 8px;
  border-top-right-radius: 8px;
}

.modal-title {
  margin: 0;
  font-size: 1.5rem;
}

.close-btn {
  background: none;
  border: none;
  font-size: 1.5rem;
  color: white;
  cursor: pointer;
  padding: 0 10px;
}

.modal-body {
  padding: 20px;
}

.loading-overlay {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: rgba(255, 255, 255, 0.7);
  z-index: 3000;
}

.user-info-card {
  background-color: #f8f9fa;
  border-radius: 8px;
}

.user-avatar {
  font-size: 3rem;
  color: #4B49AC;
  margin-right: 15px;
}

.user-stats {
  display: flex;
  gap: 15px;
  color: #6c757d;
}

.user-balance {
  color: #dc3545;
}

.user-status.online {
  color: #28a745;
  font-weight: bold;
}

/* 使用信息样式 */
.online-status-panel {
  animation: fadeIn 0.3s ease-out;
}

.usage-info {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.info-item {
  display: flex;
  justify-content: space-between;
  padding: 5px 0;
  border-bottom: 1px dashed #eee;
}

.info-label {
  font-weight: 500;
  color: #6c757d;
}

.info-value {
  font-weight: 600;
}

/* 座位布局样式 */
.seat-map-container {
  position: relative;
  height: 360px;
  border: 1px solid #dee2e6;
  border-radius: 4px;
  background-color: #f8f9fa;
  overflow: hidden;
}

.grid-container {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  grid-template-rows: repeat(10, 1fr);
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}

.grid-cell {
  border: 1px dashed #ccc;
  position: relative;
}

.grid-cell-label {
  position: absolute;
  bottom: 2px;
  right: 2px;
  font-size: 7px;
  color: #aaa;
}

.seat-item {
  position: absolute;
  background-color: #e9ecef;
  border-radius: 4px;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  font-size: 12px;
  overflow: hidden;
  cursor: default;
  border: 2px solid transparent;
  transition: all 0.2s;
}

.seat-item.available {
  background-color: #28a745;
  color: white;
  cursor: pointer;
}

.seat-item.available:hover {
  transform: translateY(-2px);
  box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}

.seat-item.unavailable {
  background-color: #dc3545;
  color: white;
  opacity: 0.7;
}

.seat-item.online {
  background-color: #007bff;
}

.seat-item.maintenance {
  background-color: #6c757d;
}

.seat-item.selected {
  border-color: #ffc107;
  box-shadow: 0 0 10px rgba(255, 193, 7, 0.5);
  z-index: 10;
}

.seat-content {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  padding: 2px;
}

.seat-name {
  font-weight: bold;
  font-size: 10px;
}

.seat-status, .seat-region, .seat-price {
  font-size: 8px;
}

.selected-info {
  background-color: #f8f9fa;
  font-weight: 500;
}

.time-display {
  font-weight: bold;
  background-color: #f8f9fa;
}

.spinning {
  animation: spin 2s linear infinite;
}

@keyframes spin {
  from { transform: rotate(0deg); }
  to { transform: rotate(360deg); }
}

/* 响应式调整 */
@media (max-width: 768px) {
  .embarkation-modal {
    width: 95%;
    max-height: 95vh;
  }
  
  .modal-body {
    padding: 15px;
  }
  
  .seat-map-container {
    height: 300px;
  }
}

/* 弹窗动画 */
@keyframes fadeIn {
  from { opacity: 0; }
  to { opacity: 1; }
}

.modal-backdrop {
  animation: fadeIn 0.3s ease-out;
}

@keyframes slideDown {
  from { transform: translateY(-20px); opacity: 0; }
  to { transform: translateY(0); opacity: 1; }
}

.embarkation-modal {
  animation: slideDown 0.3s ease-out;
}

/* 状态变化效果 */
@keyframes statusChanged {
  0% { box-shadow: 0 0 0 2px rgba(255, 193, 7, 0); transform: scale(1); }
  25% { box-shadow: 0 0 0 2px rgba(255, 193, 7, 1); transform: scale(1.05); }
  50% { box-shadow: 0 0 0 5px rgba(255, 193, 7, 0.5); transform: scale(1); }
  75% { box-shadow: 0 0 0 2px rgba(255, 193, 7, 0.8); transform: scale(1.03); }
  100% { box-shadow: 0 0 0 2px rgba(255, 193, 7, 0); transform: scale(1); }
}

.seat-item.status-changed {
  animation: statusChanged 1.5s ease-in-out 2;
  z-index: 15;
}

.refresh-info {
  font-size: 0.8rem;
  display: flex;
  align-items: center;
}

.refresh-progress {
  margin-top: 3px;
}

.progress {
  background-color: #e9ecef;
  border-radius: 2px;
  overflow: hidden;
}

.progress-bar {
  background-color: #4B49AC;
  transition: width 0.1s linear;
}
</style>